package com.huya.service.impl;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.huya.mapper.PsychologicalTestMapper;
import com.huya.mapper.TestQuestionMapper;
import com.huya.mapper.TestRecordMapper;
import com.huya.pojo.dto.AnswerSubmissionDTO;
import com.huya.pojo.entity.TestQuestion;
import com.huya.pojo.entity.TestRecord;
import com.huya.service.TestRecordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.time.LocalDateTime;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

@Service
public class TestRecordServiceImpl implements TestRecordService {
    @Autowired
    private TestRecordMapper testRecordMapper;
    @Autowired
    private TestQuestionMapper testQuestionMapper;
    @Autowired
    private PsychologicalTestMapper psychologicalTestMapper;
    @Autowired
    private ObjectMapper objectMapper;

    /**
     * 获取用户的测试记录
     * @param userId
     * @return
     */
    public List<TestRecord> getRecordsByUserId(Long userId) {
        return testRecordMapper.getRecordsByUserId(userId);
    }

    /**
     * 开始测试
     * @param userId
     * @param testId
     * @return
     */
    public String startTest(Long userId, Long testId) {
        String recordId = generateRecordId(userId);
        TestRecord testRecord = new TestRecord();
        testRecord.setRecordId(recordId);
        testRecord.setUserId(userId);
        testRecord.setTestId(testId);
        testRecord.setStartTime(LocalDateTime.now());
        testRecordMapper.insert(testRecord);
        return recordId;
    }

    /**
     * 提交测试
     * @param answerSubmissionDTO
     * @return
     */
    public TestRecord submitTest(AnswerSubmissionDTO answerSubmissionDTO) {
        TestRecord testRecord = testRecordMapper.findRecordById(answerSubmissionDTO.getRecordId());
        if (testRecord == null) {
            throw new RuntimeException("测试记录不存在");
        }
        String scoreRule = psychologicalTestMapper.getScoreRuleByTestId(testRecord.getTestId());
        int totalScore = calculateTotalScore(testRecord.getTestId(), answerSubmissionDTO.getAnswers());
        String resultLevel = evaluateResult(scoreRule, totalScore);
         testRecord.setEndTime(LocalDateTime.now());
         testRecord.setTotalScore(totalScore);
         testRecord.setResultLevel(resultLevel);
         testRecordMapper.update(testRecord);
         return testRecord;
    }

    /**
     * 生成测试记录ID
     * @param userId
     * @return
     */
    private String generateRecordId(Long userId) {
        String input = userId + LocalDateTime.now().toString();
        return DigestUtils.md5DigestAsHex(input.getBytes());
    }

    /**
     * 计算得分
     * @param testId
     * @param userAnswers
     * @return
     */
    private int calculateTotalScore(Long testId, Map<Long, String> userAnswers) {
        List<TestQuestion> questions = testQuestionMapper.getQuestionByTestId(testId);
        int totalScore = 0;

        for (TestQuestion question : questions) {
            String selectedOption= userAnswers.get(question.getQuestionId());
            if (selectedOption != null) {
                totalScore += parseOptionScore(question.getQuestionId(),selectedOption);
            }
        }
        return totalScore;
    }

    /**
     * 解析选项得分
     * @param questionId
     * @param selectedOption
     * @return
     */
    private int parseOptionScore(Long questionId, String selectedOption) {
        try {
            String optionsJson = testQuestionMapper.findOptionsById(questionId);
            JsonNode optionsNode = objectMapper.readTree(optionsJson);
            for (JsonNode option : optionsNode) {
                if (option.get("key").asText().equals(selectedOption)) {
                    return option.get("score").asInt();
                }
            }
        } catch (Exception e) {
            throw new RuntimeException("选项解析错误", e);
        }
        return 0;
    }

    /**
     *  评估结果
     * @param scoringRules
     * @param totalScore
     * @return
     */
    private String evaluateResult(String scoringRules, int totalScore) {
        try {
            JsonNode rulesNode = objectMapper.readTree(scoringRules);
            JsonNode levelsNode = rulesNode.get("levels");
            if (levelsNode != null && levelsNode.isObject()) {
                Iterator<Map.Entry<String, JsonNode>> fields = levelsNode.fields();
                while (fields.hasNext()) {
                    Map.Entry<String, JsonNode> entry = fields.next();
                    String level = entry.getKey();
                    JsonNode scoreRangeNode = entry.getValue();
                    if (scoreRangeNode != null && scoreRangeNode.isArray() && scoreRangeNode.size() == 2) {
                        int min = scoreRangeNode.get(0).asInt();
                        int max = scoreRangeNode.get(1).asInt();
                        if (totalScore >= min && totalScore <= max) {
                            return level;
                        }
                    } else {
                        throw new RuntimeException("计分规则中的得分范围格式不正确");
                    }
                }
            } else {
                throw new RuntimeException("计分规则中缺少 levels 对象");
            }
            return "未知等级";
        } catch (Exception e) {
            throw new RuntimeException("计分规则解析错误", e);
        }
    }

}
